# ImagePreview.vue
<script setup>
  import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
  import 'viewerjs/dist/viewer.css'
  import Viewer from 'viewerjs'

  const props = defineProps({
    modelValue: {
      type: Boolean,
      required: true
    },
    fileUrl: {
      type: String,
      default: ''
    },
    fileName: {
      type: String,
      default: ''
    }
  })

  const emit = defineEmits(['update:modelValue'])

  const imageRef = ref(null)
  let viewer = null

  const options = {
    inline: false,
    button: true,
    navbar: false,
    title: true,
    toolbar: {
      zoomIn: true,
      zoomOut: true,
      oneToOne: true,
      reset: true,
      prev: false,
      next: false,
      rotateLeft: true,
      rotateRight: true,
      flipHorizontal: true,
      flipVertical: true
    },
    tooltip: true,
    movable: true,
    zoomable: true,
    rotatable: true,
    scalable: true,
    transition: true,
    fullscreen: true,
    keyboard: true,
    url: 'src'
  }

  watch(
    () => props.modelValue,
    newVal => {
      if (newVal && viewer) {
        viewer.show()
      }
    }
  )

  watch(
    () => props.fileUrl,
    newVal => {
      if (newVal && imageRef.value) {
        // 需要在 nextTick 后更新图片源
        nextTick(() => {
          if (viewer) {
            viewer.update()
          }
        })
      }
    }
  )

  const handleClose = () => {
    emit('update:modelValue', false)
  }

  onMounted(() => {
    // 初始化 viewer
    viewer = new Viewer(imageRef.value, {
      ...options,
      hidden: () => {
        handleClose()
      },
      title: [true, () => `${props.fileName || '图片预览'}`]
    })
  })

  onBeforeUnmount(() => {
    if (viewer) {
      viewer.destroy()
    }
  })
</script>

<template>
  <div style="display: none">
    <img ref="imageRef" :alt="fileName" :src="fileUrl" />
  </div>
</template>

<style lang="less" scoped>
  // 自定义查看器样式
  :deep(.viewer-toolbar) {
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    overflow: hidden;

    & > ul {
      display: flex;
      align-items: center;
      padding: 4px;

      & > li {
        background-color: transparent;

        &:hover {
          background-color: rgba(255, 255, 255, 0.1);
        }

        &:active {
          background-color: rgba(255, 255, 255, 0.2);
        }
      }
    }
  }

  :deep(.viewer-title) {
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    padding: 8px 16px;
  }

  :deep(.viewer-button) {
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 50%;

    &:hover {
      background-color: rgba(0, 0, 0, 0.7);
    }
  }
</style>
